# coding:utf-8
import csv
import glob
import os

import pandas as pd
import numpy as np

# names = ['powerX', 'powerY', 'powerZ', 'vibrationX', 'vibrationY', 'vibrationZ', 'xunhao']
Adir = r'F:\Archive\TrainA'
AAcsv = r'F:\Archive\newdata\onefeature\aofeature.csv'

# all_features = ['平均值','方根幅值','均方根','绝对平均幅值','标准差','功率谱平均值','幅值谱平均值','幅值谱最大值',
#                 '相位谱平均值','相位谱最大值','A4能量比']
# all_features = ['平均值','方根幅值','均方根','绝对平均幅值','标准差','功率谱平均值','幅值谱平均值','幅值谱最大值',
#                 '相位谱平均值','相位谱最大值','A4能量比']
all_features = ['均值','方根幅值','均方根','平均幅值','标准差','均方值','方根均值','歪度值','峭度值','波形指标','脉冲指标','歪度指标',
                '峰值指标','裕度指标','峭度指标']
def pull_feature(data:pd.Series,N):
    li = []
    size = data.size
    # print('data size', data.size)
    fftdata = np.fft.fft(data)
    fftdata /= len(data)
    absdata = np.abs(data)
    # print(f'abs:{absdata}')

    # 均值
    sumD = data.sum()  # y方向力总和
    print('sumD', sumD)
    MV: np.float64 = sumD / N
    print(f'均值:{MV},{type(MV)}')
    li.append(MV)

    # 方根幅值
    SRam = np.square(np.sum(np.sqrt(absdata)) / N)
    print(f'方根幅值:{SRam},{type(SRam)}')
    li.append(SRam)

    # 均方根
    root_mean_score = np.sqrt(np.sum(np.square(data)) / size)
    print(f'均方根值:{root_mean_score},{type(root_mean_score)}')
    li.append(root_mean_score)

    # 平均幅值
    Mam = absdata.sum() / N
    print(f'平均幅值:{Mam},{type(Mam)}')
    li.append(Mam)

    # 标准差
    std1 = ((data - MV) ** 2).sum()  # fixme:data or np.abs(data)
    std: np.float64 = np.sqrt(std1 / (N - 1))
    print(f'标准差:{std},{type(std)}')
    li.append(std)

    # 均方值
    # square = data * data
    # MSV: np.float64 = square.sum() / N
    # print(f'均方值:{MSV},{type(MSV)}')
    # li.append(MSV)

    # 方根均值
    sqMean = np.sqrt(absdata)
    sqSum = sqMean.sum()
    SMRoot: np.float64 = sqSum / np.sqrt(std)
    print(f'方根均值:{SMRoot},{type(SMRoot)}')
    li.append(SMRoot)

    # 歪度值
    skewness = np.sum(np.power(data, 3)) / size
    print(f'歪度值:{skewness},{type(skewness)}')
    li.append(skewness)

    # 峭度值
    Kurtosis_value = np.sum(np.power(data, 4)) / size
    print(f'峭度值:{Kurtosis_value},{type(Kurtosis_value)}')
    li.append(Kurtosis_value)

    # 波形指标
    absolute_mean_value = np.sum(np.fabs(data)) / size  # 绝对平均值
    # shape_factor = root_mean_score / absolute_mean_value
    # print(f'波形指标:{shape_factor},{type(shape_factor)}')
    # li.append(shape_factor)

    # 脉冲指标
    pulse_factor = np.max(data) / absolute_mean_value
    print(f'脉冲指标:{pulse_factor},{type(pulse_factor)}')
    li.append(pulse_factor)

    # 歪度指标
    Crooked_factor = Kurtosis_value / root_mean_score
    print(f'歪度指标:{Crooked_factor},{type(Crooked_factor)}')
    li.append(Crooked_factor)

    # 峰值指标
    crest_factor = np.max(data) / root_mean_score
    print(f'峰值指标:{crest_factor},{type(crest_factor)}')
    li.append(crest_factor)

    # 裕度指标
    Root_amplitude = np.square(np.sum(np.sqrt(np.fabs(data))) / size)  # 方根幅值
    clearance_factor = np.max(data) / Root_amplitude
    print(f'裕度指标:{clearance_factor},{type(clearance_factor)}')
    li.append(clearance_factor)

    # 峭度指标
    Kurtosis_factor = Kurtosis_value / np.power(root_mean_score, 4)
    print(f'峭度指标:{Kurtosis_factor},{type(Kurtosis_factor)}')
    li.append(Kurtosis_factor)
    return li

# 一组（很多个）频率成整数倍的正弦波
def fetch_feature(data:pd.Series,N):
    li = []
    size = data.size
    # print('data size', data.size)
    fftdata = np.fft.fft(data)
    fftdata /= len(data)
    absdata = np.abs(data)
    # print(f'abs:{absdata}')

    # 均值
    sumD = data.sum()  # y方向力总和
    print('sumD', sumD)
    MV: np.float64 = sumD / N
    print(f'均值:{MV},{type(MV)}')
    li.append(MV)

    # 方根幅值
    SRam = np.square(np.sum(np.sqrt(absdata))/ N)
    print(f'方根幅值:{SRam},{type(SRam)}')
    li.append(SRam)

    # 均方根
    root_mean_score = np.sqrt(np.sum(np.square(data)) / size)
    print(f'均方根值:{root_mean_score},{type(root_mean_score)}')
    li.append(root_mean_score)

    # 平均幅值
    Mam = absdata.sum() / N
    print(f'平均幅值:{Mam},{type(Mam)}')
    li.append(Mam)

    # 标准差
    std1 = ((data - MV) ** 2).sum()  # fixme:data or np.abs(data)
    std: np.float64 = np.sqrt(std1 / (N - 1))
    print(f'标准差:{std},{type(std)}')
    li.append(std)

    # 功率谱平均值
    # ps = np.fft.fft(data) ** 2
    # ps /= len(ps)
    # GLm = np.mean(ps)
    # print(f"功率谱平均值:{GLm}")
    # li.append(GLm)

    # 幅值谱平均值
    fudupu = np.abs(fftdata)  # 幅度谱
    fuduME = np.mean(fudupu)  # 求模长
    print(f"幅度谱平均值:{fuduME},{type(fuduME)}")
    li.append(fuduME)

    # 幅值谱最大值
    fuduMAX = np.max(fudupu)  # 求模长
    print(f"幅度谱平均值:{fuduMAX},{type(fuduMAX)}")
    li.append(fuduMAX)

    # 相位谱平均值
    xiangweipu = np.angle(fftdata)
    xiangweiME = np.mean(xiangweipu)
    print(f"相位谱平均值:{xiangweiME},{type(xiangweiME)}")
    li.append(xiangweiME)

    # 相位谱最大值
    xiangweiMAX = np.max(xiangweipu)
    print(f"相位谱最大值:{xiangweiMAX},{type(xiangweiMAX)}")
    li.append(xiangweiMAX)

    # TODO:A4能量比
    return li

def cal_feature(data: pd.Series, N):
    print('data size', data.size)
    absdata = np.abs(data)
    # print(f'abs:{absdata}')
    # 均值
    print('data,', data)
    sumD = data.sum()  # y方向力总和
    print('sumD', sumD)
    MV: np.float64 = sumD / N
    print(f'均值:{MV},{type(MV)}')

    # 平均幅值
    Mam = absdata.sum() / N
    print(f'平均幅值:{Mam},{type(Mam)}')

    # 方根幅值
    SRam = np.square(np.sqrt(absdata) / N)
    print(f'方根幅值:{SRam},{type(SRam)}')

    # 均方值
    square = data * data
    MSV: np.float64 = square.sum() / N
    print(f'均方值:{MSV},{type(MSV)}')

    # 标准差
    std1 = ((data - MV) ** 2).sum()  # fixme:data or np.abs(data)
    std: np.float64 = np.sqrt(std1 / (N - 1))
    print(f'标准差:{std},{type(std)}')

    # 方根均值
    sqMean = np.sqrt(absdata)
    sqSum = sqMean.sum()
    SMRoot: np.float64 = sqSum / np.sqrt(std)
    print(f'方根均值:{SMRoot},{type(SMRoot)}')

    # 波高率
    waveMaxRate: np.float64 = np.max(data) / std
    print(f'波高率:{waveMaxRate},{type(waveMaxRate)}')

    # 波形率
    waveShapeRate: np.float64 = std / data.max()  # FIXME:data or data.max()?
    print(f'波形率:{waveShapeRate},{type(waveShapeRate)}')

    # 绝对值总和
    AS: np.float64 = np.sum(absdata)
    print(f'绝对值总和:{AS},{type(AS)}')

    # 歪度
    CrookedDegree1 = np.sum((absdata - std) ** 3)
    CrookedDegree: np.float64 = CrookedDegree1 / (std ** 3)
    print(f'歪度:{CrookedDegree},{type(CrookedDegree)}')

    # 自乘均值
    SMM: np.float64 = (data ** 2).sum() / (std ** 2)
    print(f'自乘均值:{SMM},{type(SMM)}')

    # 极大值
    MaxV: np.float64 = data.max()
    print(f'极大值:{MaxV},{type(MaxV)}')

    # 绝对均值
    absM: np.float64 = absdata.sum() / N
    print(f'绝对均值:{absM},{type(absM)}')

    return [MV, MSV, SMRoot, waveMaxRate, waveShapeRate, std, AS, CrookedDegree, SMM, MaxV, absM]


def get_file_feature(data: pd.Series, N):  # 获取单一表格中的10个特征
    li = []
    size = data.size
    # 最大值
    max = np.max(data)
    li.append(max)
    # 均方根值
    root_mean_score = np.sqrt(np.sum(np.square(data)) / size)
    li.append(root_mean_score)
    # 歪度值
    skewness = np.sum(np.power(data, 3)) / size
    li.append(skewness)
    # 峭度值
    Kurtosis_value = np.sum(np.power(data, 4)) / size
    li.append(Kurtosis_value)
    # 波形指标
    absolute_mean_value = np.sum(np.fabs(data)) / size  # 绝对平均值
    shape_factor = root_mean_score / absolute_mean_value
    li.append(shape_factor)
    # 脉冲指标
    pulse_factor = max / absolute_mean_value
    li.append(pulse_factor)
    # 歪度指标
    Kurtosis_factor = Kurtosis_value / root_mean_score
    li.append(Kurtosis_factor)
    # 峰值指标
    crest_factor = max / root_mean_score
    li.append(crest_factor)
    # 裕度指标
    Root_amplitude = np.square(np.sum(np.sqrt(np.fabs(data))) / size)  # 方根幅值
    clearance_factor = max / Root_amplitude
    li.append(clearance_factor)
    # 峭度指标
    Kurtosis_factor = Kurtosis_value / np.power(root_mean_score, 4)
    li.append(Kurtosis_factor)
    return li


def pinglv(data: pd.Series,N):
    lii = []

    fftdata = np.fft.fft(data)
    fftdata /= len(data)

    # 幅度谱
    fudupu = np.abs(fftdata)  # 幅度谱
    fudu = np.linalg.norm(fudupu, ord=2)  # 求模长
    print("幅度谱", fudu)
    lii.append(fudu)

    # 相位谱
    xiangweipu = np.angle(fftdata)
    xiangwei = np.linalg.norm(xiangweipu, ord=2)
    print("相位谱", xiangwei)
    lii.append(xiangwei)

    # 功率谱
    ps = np.fft.fft(data) ** 2
    ps /= len(ps)
    gonglv = np.linalg.norm(ps, ord=2)
    print("功率谱",gonglv)
    lii.append(gonglv)

    return lii


def total_cal(Adir):
    cwf = csv.writer((open(AAcsv, 'w', encoding='utf-8', newline='')))
    for fcsv in os.listdir(Adir):
        fcsv = os.path.join(Adir, fcsv)
        data = pd.read_csv(fcsv, header=None)
        # print(f'data shape:{data.head()}')
        N = len(data.index)
        lenColumns = len(data.columns)
        features = []
        for i in range(0, lenColumns):
            tfeature = pull_feature(data.ix[:, i], N)
            # print('tfeature',tfeature)
            features.extend(tfeature)
        # print(f'features',features,'\n\n')
        cwf.writerow(features)


if __name__ == "__main__":
    total_cal(Adir)
    # print(len(all_features.clear()))